#ifndef SOCKET_H
#define SOCKET_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#include <iostream>
#include <cstdlib>
#include <strings.h>

#include <string>

using namespace std;

/**
 * \brief Socket creator
 *
 * This class provides a socket
 */

class Socket
{

protected:

    int _sockfd; /** Socket file descriptor. */
    int _portno; /** Socket port . */
    struct sockaddr_in _serv_addr; /** Server's adress (struct). */
    struct hostent *_server; /** Server pointer (Struct). */


public:

    /**
     * \brief Default constructor.
     */

    Socket();

    /**
     * \brief Get the socket file descriptor.
     *
     * \return the socket file descriptor number.
     */
    int getSockfd();

    /**
     * \brief Get the socket port.
     *
     * \return the socket port number
     */
    int getPortno();

    /**
     * \brief Get &_serv_addr (Struct sockaddr_in).
     *
     * \return pointer to _serv_addr (Struct sockaddr_in).
     */
    struct sockaddr_in* getServ_addr();

    /**
     * \brief Get _server (Struct hostent).
     *
     * \return pointer _server (Struct hostent).
     */
    struct hostent *getServer();

    /**
     * \brief Set the socket file descriptor.
     *
     * \param sockfd Socket file descriptor number
     */
    void setSockfd(int sockfd);

    /**
     * \brief Set the socket port number
     *
     * \param portno Socket port number
     */
    void setPortno(int portno);

    /**
     * \brief Set the server adress
     *
     * \param sockaddr_in A struct which contains the server adress
     */
    void setServ_addr(struct sockaddr_in);

    /**
     * \brief Set the hostent struct with the server data
     *
     * \param server Pointer to the server node
     */
    void setServer(struct hostent *server);

    /**
     * \brief Print all the parameters of _server_add and _server to control their evolution
     *
     */
    void printAll();

    /**
     * \brief Overload the operator <<, which calls the function write (UDP -> sendto)
     *
     * \note This overload simplifies the exchange of data between server and client
     *
     * \param data Information sended
     */
    Socket & operator << (string data);

    /**
     * \brief Overload the operator >>, which calls the function read (UDP -> recvfrom)
     *
     * \note This overload simplifies the exchange of data between server and client
     *
     * \param data Information received ()
     */
    Socket & operator >> (string & data);

    /**
     * \brief Pure virtual function to write in a socket.
     *
     * \note This is the virtual function called by the operator <<
     * \note Afterwards, we made another polimorphic functions in her childrens.
     * \param data Information sended
     */
    virtual void write(string data)=0;

    /**
     * \brief Pure virtual function to read from a socket.
     *
     * \note This is the virtual function called by the operator >>
     * \note Afterwards, we made another polimorphic functions in her childrens.
     * \param data Information recived
     */
    virtual void read (string &data)=0;

    /**
     * \brief Prints a string with the error produced
     *
     * \param string The name of the error (bind, connect, ...)
     */
    void error(string);

};
#endif // SOCKET_H
